/*-
 * Copyright (c) 2006, 2007 FTS Team
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the FTS Team nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      SnippetCollector.hpp
 *
 * $FTS$
 */
#include <SnippetCollector.hpp>

#include <Document.hpp>
#include <DocumentStorage.hpp>
#include <IRConfig.hpp>
#include <OutputDataCollector.hpp>
#include <Passage.hpp>
#include <RankedDocument.hpp>


namespace FTSS // FullTextSearchSystem
{

//
// Constructor
//
SnippetCollector::SnippetCollector(OutputDataCollector  * pICollector,
                                   DocumentStorage      * pIDocumentStorage,
                                   IRConfig             * pIIRConfig): pCollector(pICollector),
                                                                       pDocumentStorage(pIDocumentStorage),
                                                                       pIRConfig(pIIRConfig) { ;; }

//
// Start of output
//
INT_32 SnippetCollector::StartOutput(W_FLOAT dExecTime, const INT_32 & iDocumentsCount, const TermStatistic * aTerms, const INT_32 & iTermsCount)
{
	UINT_64 iSec  = UINT_64(dExecTime);
	UINT_64 iUSec = UINT_64((dExecTime - iSec) * 1000000.0);

	iMaxDocuments     = pIRConfig -> GetInt32("SnippetCollector/MaxDocuments",       100);
	iMaxSnippetLength = pIRConfig -> GetInt32("SnippetCollector/MaxSnippetLength",   100);
	sHLStartTag       = pIRConfig -> GetString("SnippetCollector/HighlightStartTag", "***");
	sHLEndTag         = pIRConfig -> GetString("SnippetCollector/HighlightEndTag",   "***");

	iRegisteredDocuments = 0;

	pCollector -> ExecTime(iSec, iUSec);

	pCollector -> StartOutput(iDocumentsCount, aTerms, iTermsCount);
return 0;
}

//
// Add document to result set
//
INT_32 SnippetCollector::AddDocument(const RankedDocument & oRankedDocument)
{
	using STLW::vector;

	if (iRegisteredDocuments == iMaxDocuments) { return 0; }

	pCollector -> StartDocument(oRankedDocument.document_info, oRankedDocument.rank);

	Document * pDocument = pDocumentStorage -> GetDocument(oRankedDocument.document_info -> doc_core_id);

//	oRankedDocument.PrintDocument();
	if (pDocument != NULL)
	{
		for (UINT_32 iI = 0; iI < oRankedDocument.snippets_num; ++iI)
		{
			pCollector -> StartSnippet();

			UINT_32 iSnippetPos     = oRankedDocument.snippets[iI].base_points[0];

			UINT_32 iTermLength = 0;
			CCHAR_P sTerm       = NULL;
//fprintf(stderr, "oRankedDocument.snippets[%d].base_points_num = %d\n",iI, oRankedDocument.snippets[iI].base_points_num);
			UINT_32 iAroundSnippetText = iSnippetPos > (iMaxSnippetLength / 2) ? (iSnippetPos - iMaxSnippetLength / 2) : 0;
			sTerm = pDocument -> GetTermRange(iAroundSnippetText, iSnippetPos, iTermLength);
			pCollector -> AddSnippetData(sTerm, iTermLength);

			UINT_32 iJ = 0;
			for(; iJ < oRankedDocument.snippets[iI].base_points_num; ++iJ)
			{
				UINT_32 iTermPos = oRankedDocument.snippets[iI].base_points[iJ];
				if (iSnippetPos <= iTermPos - 1)
				{
					sTerm = pDocument -> GetTermRange(iSnippetPos - 1, iTermPos, iTermLength);
					pCollector -> AddSnippetData(sTerm, iTermLength);
				}
//fprintf(stderr, "iTermPos = %d\n", iTermPos);
				sTerm = pDocument -> GetTerm(iTermPos, iTermLength);
				pCollector -> AddTerm(sHLStartTag.c_str(), sHLStartTag.length());
				pCollector -> AddTerm(sTerm, iTermLength);
				pCollector -> AddTerm(sHLEndTag.c_str(), sHLEndTag.length());

				iSnippetPos = iTermPos + 1;
			}

			if (iJ > 0)
			{
				iAroundSnippetText = iSnippetPos + iMaxSnippetLength / 2;
				sTerm = pDocument -> GetTermRange(iSnippetPos, iAroundSnippetText, iTermLength);
				pCollector -> AddSnippetData(sTerm, iTermLength);
			}

			pCollector -> EndSnippet();
		}
		Document::DestroyDocument(pDocument);
		++iRegisteredDocuments;
	}
	pCollector -> EndDocument();

return 0;
}

//
// End of output
//
INT_32 SnippetCollector::EndOutput()
{
	pCollector -> EndOutput();
	iRegisteredDocuments = 0;
return 0;
}

//
// A destructor
//
SnippetCollector::~SnippetCollector() throw() { ;; }

} // namespace FTSS
// End.
